package com.hissy.cn.redis;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Protocol;

/**
 * @author zhangyanfei
 * @brief Jedis连接池工厂
 * @details
 * 目前支持一个jvm一个jedis连接配置，同时对应一个连接池实例
 * 后续支持一个jvm多个jedis连接配置时，提供多个连接池实例
 *
 */
public class NJedisPoolFactory {

    private static final Logger logger = LoggerFactory.getLogger(NJedisPoolFactory.class);

    // 默认最大空闲连接数
    private static final int DEFAULT_MAXIDLE = 10;

    // 默认最大连接数
    private static final int DEFAULT_MAXTOTAL = 50;

    // 默认获取连接时的最大等待毫秒数
    private static final int DEFAULT_MAXWAITMILLIS = 2000;

    // 默认database
    private static final int DEFAULT_DATABASE = 4;


    public static JedisPool getJedisPool (JedisPoolBean properties) {
        // valid properties
        NJedisPoolFactory.validProperties(properties);

        // create JedisPoolConfigBean
        JedisPoolConfig jedisPoolConfig = NJedisPoolFactory.createJedisPoolConfigBean(properties);

        // init parameters or judge if load the default values
        final int dataBase = properties.getRedisDatabase() == 0 ? DEFAULT_DATABASE : properties.getRedisDatabase();
        final String redisHost = properties.getRedisHost();
        final String redisPassword = properties.getRedisPassword();
        final int redisPort = properties.getRedisPort();

        logger.info("【JedisPool】init JedisPool with the [{}] config, (redisHost):{}、(dataBase):{}", properties.getNamespace(), redisHost, dataBase);
        // 不需要密码

        //return new JedisPool(jedisPoolConfig, redisHost, redisPort,Protocol.DEFAULT_TIMEOUT);

        return new JedisPool(jedisPoolConfig, redisHost, redisPort, Protocol.DEFAULT_TIMEOUT, redisPassword,
            dataBase);
    }


    /**
     * 配置文件属性校验
     * @param properties 配置文件属性对象
     * @return void
     * @author sxx
     * @date 2018-08-10 10:29
     * @note sxx@2018-08-10 10:29创建
     */
    private static void validProperties (JedisPoolBean properties) {
        final String redisHost = properties.getRedisHost();
        final String redisPassword = properties.getRedisPassword();
        final int redisPort = properties.getRedisPort();

        // verify parameters
        if (StringUtils.isBlank(redisHost)) {
            throw new NullPointerException("redisHost can't be null !");
        }

        if (0 == redisPort) {
            throw new NullPointerException("redisPort can't be 0 !");
        }

        if(StringUtils.isBlank(redisPassword)){
            // 置为空 避免redis的 auth
            properties.redisPassword=null;
        }
    }

    /**
     * 创建jedispoolconfig bean
     * @param properties
     * @return redis.clients.jedis.JedisPoolConfig
     * @date 2018-08-10 10:36
     */
    private static JedisPoolConfig createJedisPoolConfigBean (JedisPoolBean properties) {
        // init parameters or judge if load the default values
        final int maxIdle = properties.getMaxIdle() == 0 ? DEFAULT_MAXIDLE: properties.getMaxIdle();
        final int maxTotal = properties.getMaxTotal() == 0 ? DEFAULT_MAXTOTAL : properties.getMaxTotal();
        final int maxWaitMillis = properties.getMaxWaitMillis() == 0 ? DEFAULT_MAXWAITMILLIS : properties.getMaxWaitMillis();

        // wrapper bean
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxTotal(maxTotal);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        jedisPoolConfig.setTestOnBorrow(false);
        jedisPoolConfig.setTestOnCreate(false);
        jedisPoolConfig.setTestOnReturn(false);
        jedisPoolConfig.setTimeBetweenEvictionRunsMillis(2000);

        // logout jedispool info
        logger.info("【jedisPoolConfig】begin JedisPool initting, {} jedisPoolConfig properties: maxIdle:{}, maxTotal:{}, maxWait:{}",
                properties.getNamespace(),
                maxIdle,
                maxTotal,
                maxWaitMillis);

        return jedisPoolConfig;
    }
}
